使用 Java 通过数据库连接(JDBC)访问和操作 Oracle 自定义类型.
大致就是这个网页中说的. https://docs.oracle.com/cd/E1...

Oracle中支持在数据库中定义数据格式.(嵌套数据格式)
在JAVA中调用时,传入相应格式的数据即可.
找了下没找到对应资料,记录下.
只是找到了一种简单的可行方案,因为有人专门写PLSQL来处理逻辑,所以将逻辑全部放在数据库中处理,JAVA这边弄点简单代码传数据就行.

CREATE TYPE TDC_SUPPLIER_ADDR AS OBJECT
            (ADDRESS VARCHAR2(240),ADDRESS_ID NUMBER);
            
CREATE TYPE TDC_SUPPLIER_ADDR_L AS TABLE OF TDC_SUPPLIER_ADDR;
 
CREATE TYPE TDC_SUPPLIER AS OBJECT
            (NAME VARCHAR2(50),SUPPLIER_ID NUMBER, ADDR TDC_SUPPLIER_ADDR_L);
            
CREATE TABLE TDC_TEST (
TEXT VARCHAR2(2000));
 
CREATE OR REPLACE PACKAGE TDC_TEST_PKG IS
 
  PROCEDURE CREATE_SUPPLIER (
    SUP_OBJ IN TDC_SUPPLIER);
END TDC_TEST_PKG;
 
CREATE OR REPLACE PACKAGE BODY TDC_TEST_PKG IS
 
  PROCEDURE CREATE_SUPPLIER (
    SUP_OBJ IN TDC_SUPPLIER) IS 
    
    
  BEGIN
    INSERT INTO TDC_TEST VALUES (SUP_OBJ.NAME);
    
    COMMIT;
  END CREATE_SUPPLIER;
END TDC_TEST_PKG;

上面的SQL是个简单的例子.
声明了一个数据类型TDC_SUPPLIER, 在 call CREATE_SUPPLIER 时需要传入TDC_SUPPLIER类型数据作为参数.
其中将TDC_SUPPLIER转换为json,大致是下面的格式

{
"NAME":"",
"SUPPLIER_ID":0,
"ADDR": [
  {
    "ADDRESS": "",
    "ADDRESS_ID": 0
  },
  {
    "ADDRESS": "",
    "ADDRESS_ID": 0
  }
]
}

其中定义了一个TDC_SUPPLIER_ADDR数据类型.里面有ADDRESS和ADDRESS_ID属性.
定义了一个TDC_SUPPLIER_ADDR_L数组,里面包含多项TDC_SUPPLIER_ADDR
在将TDC_SUPPLIER_ADDR_L作为TDC_SUPPLIER的一个属性.

参考该链接实现代码

package com.hktdc.po.api.approval.test;

import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Test2 {

    private final Logger logger = LoggerFactory.getLogger(Test1.class);

    public static void main(String[] args)
            throws ClassNotFoundException, SQLException {
        DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
        // 打开数据库连接
        String url = "jdbc:oracle:thin:@//127.0.0.1:1521/DB";
        Connection conn = DriverManager.getConnection(url, "apps", "apps");
        conn.setAutoCommit(false);

        // StructDescriptor.createDescriptor 表示要在JAVA中创建与数据库对应的对象.第一个参数是数据库中的类型名称
        StructDescriptor addDesc = StructDescriptor.createDescriptor("TDC_SUPPLIER_ADDR", conn);
        /*
        通过 new STRUCT 方法,将JAVA 中的参数转换为数据库中的对象.
        第一个参数为数据库类型名称对象
        第二个参数为数据库连接
        第三个参数为object数组,表示对象中的值.注意:对象中值的类型,应该与数据库中对应参数类型一致.
         */
        Object[] addArr = {"南山区", 10001};
        STRUCT addRecord = new STRUCT(addDesc, conn, addArr);
        Object[] addArr2 = {"龙岗区", 10001};
        STRUCT addRecord2 = new STRUCT(addDesc, conn, addArr2);

        /*
        构建嵌套对象.
        StructDescriptor 只需要定义数据库中 CREATE TYPE ** AS OBJECT 的类型即可.
        TDC_SUPPLIER_ADDR_L 在数据库中代表多个 TDC_SUPPLIER_ADDR,不需要在JAVA中定义,只需要将多个 TDC_SUPPLIER_ADDR 转换成 Object 数组即可
         */
        StructDescriptor supDesc = StructDescriptor.createDescriptor("TDC_SUPPLIER", conn);
        Object[] addLData = {addRecord, addRecord2};
        Object[] data = {"张三", 302, addLData};
        STRUCT supplier = new STRUCT(supDesc, conn, data);

        // 创建一个调用语句
        CallableStatement stmt = conn.prepareCall("{ call TDC_TEST_PKG.CREATE_SUPPLIER(?) }");

        // 绑定输入记录,设置第一个 ? 代表的参数
        stmt.setObject(1, supplier);
        // 执行SQL
        stmt.execute();

    }
}

无趣
1.5k 声望17 粉丝

胸大有什么用,爽的是别人,又不是自己.